<?php


namespace App\Model\Logic;


use App\Helper\RedisConst;
use App\Model\Entity\Challenge;
use App\Model\Entity\PostChallenge;
use App\Model\Entity\PostExtends;
use App\Model\Entity\Posts;
use App\Model\Entity\Video;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Bean\Annotation\Mapping\Inject;
use Swoft\Redis\Pool;

/**
 * @Bean()
 * Class PostEsLogic
 * @package App\Model\Logic
 */
class PostEsLogic extends ElasticSearchLogic
{

    const INDEX = 'vaffle-posts';

    const TYPE = 'posts';

    /**
     * @Inject()
     * @var Pool
     */
    private $redis;

    /**
     * @Inject("redisMQ.pool")
     * @var Pool
     */
    private $redis_mq;


//    public function __construct($host = null)
//    {
//        parent::__construct($host);
//    }

    /**
     * --------------------------------------------------------------------------
     * 插入post 数据
     * --------------------------------------------------------------------------
     * @param $id
     */
    public function insert($id)
    {
        $es_post = $this->getPostById($id);
        $method = $es_post ? 'edit' : 'add';
        $post_data = $this->buildPostEsData($id, $method);
        if(!$post_data) {return;}
        try{
            $params = [
                'index' => self::INDEX,
                'type' => self::TYPE,
                'id' => $post_data['id'],
                'body' => $post_data
            ];
            if($method === 'edit') $this->redis->del(RedisConst::TMP_RENDER_POST . $id);
            $this->client->index($params);
            //图片鉴黄
            if($method == 'add'){
                $this->redis_mq->rpush(RedisConst::REKOGNITION_MQ, $post_data['id']);
            }
        }catch (\Exception $e){
            //存储失败队列
            $this->redis_mq->rpush(RedisConst::FAILED_POST_ES_ID, $id);
            return ;
        }
    }

    /**
     * --------------------------------------------------------------------------
     * 根据post id查询post数据
     * --------------------------------------------------------------------------
     * @param $post_id
     * @return array
     */
    public function getPostById($post_id)
    {
        $data = $this->getItemById(self::INDEX, self::TYPE, $post_id);
        if(!$data) return [];
        return $data['_source'];
    }

    /**
     * --------------------------------------------------------------------------
     * 更新post文档
     * --------------------------------------------------------------------------
     * @param $id
     * @param $data
     */
    public function updatePost($id, $data)
    {
        $params = [
            'index' => self::INDEX,
            'type' => self::TYPE,
            'id' => $id,
            'body' => [
                'doc' => $data
            ]
        ];
        $this->update($params);
    }


    /**
     * --------------------------------------------------------------------------
     * 删除数据
     * --------------------------------------------------------------------------
     * @param $id
     */
    public function delete($id)
    {
        $is_exist = $this->getPostById($id);
        if(!$is_exist) return;
        $params = [
            'index' => self::INDEX,
            'type' => self::TYPE,
            'id' => $id,
        ];
        $this->delete($params);
    }


    /**
     * --------------------------------------------------------------------------
     * 构建post es数据
     * --------------------------------------------------------------------------
     * @param $id
     * @param string $method
     * @return bool
     * @throws \Exception
     */
    public function buildPostEsData($id, $method = 'add')
    {
        try{
            $posts = Posts::where('id', $id)->first();
            if(!$posts) return;
            $extends = PostExtends::where('post_id', $id)->first();
            if($posts->type == 3){
                $video = Video::where('post_id', $id)->where('status',1)->first();
            }
            $images = Posts::getPostPictures($id);
            //是否是转发贴
            if($posts->original){
                $original = Posts::where('id', $posts->original)->first();
                $original->content = $original->content ? $original->content : '';
                $video = Video::where('post_id', $posts->original)->first();
                $images = Posts::getPostPictures($posts->original);
            }
            if($images) {
                $images = Comm::buildImg($images);
            }
            $content = ($posts->original) ? $original->content :  trim($posts->content);
            $content = trim($content) ? trim($content) : '';
            $data = [
                'member_id' => (int)$posts->member_id,
                'content' => $content,
                'publish_addr' => $posts->publish_addr,
                'publish_ip' => $posts->publish_ip,
                'from_device' => (int)$posts->from_device,
                'from_version' => $posts->from_version,
                'tag_ids' => '',
                'type' => intval($posts->type),
                'created_at' => intval($posts->created_at),
                'id' => intval($posts->id),
                'category' => $posts->category,
                'title' => $posts->title ? $posts->title : '',
                'platform' => intval($posts->platform),
                'collect_num' => intval($extends->collect_num),
                'comments_num' => intval($extends->comments_num),
                'praise_num' => intval($extends->praise_num),
                'share_num' => intval($extends->share_num),
                'click_num' => intval($extends->click_num),
                'read_num' =>  intval($extends->read_num),
                'answer_num' => intval($extends->answer_num),
                'original' => intval($posts->original),
                'video' => isset($video) ? $video->path_url : '',
                'video_cover' => isset($video) && $video->cover ? $video->cover : '',
                'video_cover_ratio' => isset($video) && $video->cover ? Comm::videoCoverRatio($video->ratio) : 0,
                'status' => intval($posts->status),
                'is_robot' => intval($posts->is_robot),
                'trans' => isset($video)  ? intval($video->trans) : 0,
                'publish_coordinate' => '',
                'images' => ($posts->type == 2) ? json_encode($images) : "",
                'repeat_content' => intval($posts->original) ? $posts->content : '',
                'brand_topic_id' => intval($posts->topic_id),
                'brand_id' => intval($posts->brand_id),
                'is_choiceness' => intval($posts->is_choiceness),
                'is_brand_notice' => intval($posts->is_notice),
                'is_deals' => intval($posts->is_deals),
                'shop_id' => intval($posts->shop_id),
                'shop_score' => intval($posts->shop_score),
                'is_business_account' => intval($posts->is_business_account),
                'nation_code3' => $posts->nation_code3 ? strtoupper($posts->nation_code3) : '',
                'is_whole' => $posts->is_whole ? intval($posts->is_whole) : 0,
                'offset' =>  $this->getPostOffset($id),
                'aztec_images' => $posts->aztec_images ? $posts->aztec_images : "",
                'review_product' => $posts->review_product ? $posts->review_product : "",
                'review_type' => $posts->review_type ? $posts->review_type : '',
                'recommend_state' => $this->getPostOffsetRecommendState($id),
            ];

            //hotnews 的标签数据
            if($posts->category == 'hotnews')
            {
                $data['tags'] = (new HotnewsTag())->getTagsByNewsId($posts->id);
            }

            //写入challenge信息
            $data['challenge'] = '';
            $data['challenge_item'] = '';
            $ch = PostChallenge::where('post_id', $data['id'])->first();
            $challenge_id = $ch ? intval($ch->challenge_id) : 0;
            if($challenge_id){
                $challenge = Challenge::where('id', $challenge_id)->first();
                if($challenge){
                    $data['challenge'] = json_encode([
                        'them' => $challenge->them,
                        'challenge_id' => $challenge_id
                    ]);
                    $data['challenge_item'] = $challenge->them;
                    $data['challenge_id'] = intval($challenge_id);
                }
            }

            $topic_ids = Posts::addTopic($data['content'] . ' ' . $data['repeat_content'], 'post');
            $data['topic'] = $topic_ids ? json_encode($topic_ids) : '';
            // @功能
            $attention = new Attention();
            $at_members = $attention->getAttentionMember($data['content'] . ' ' . $data['repeat_content']);
            $data['attention'] = '';
            if($at_members && $method == 'add')
            {
                $attention->addAttention($at_members['member_ids'], $data['id'], 'post', $data['member_id']);
                $data['attention'] = JSON($at_members);
                $uids = array_values($at_members['member_ids']);
                if($data['status']) $attention->pushAttentionTips($uids, $data['member_id']);
            }
            //编辑时需要推送的人
            if($at_members && $method == 'edit')
            {
                $es_post = $this->getPostById($id);
                if($es_post){
                    $attention->addAttention($at_members['member_ids'], $data['id'], 'post', $data['member_id']);
                    $data['attention'] = JSON($at_members);
                    $uids = array_values($at_members['member_ids']);
                    $old_ids = $es_post['attention'] ?  json_decode($es_post['attention'], true) : [];
                    if($old_ids){
                        $old_ids = array_values($old_ids['member_ids']);
                        $uids = array_diff($uids, $old_ids);
                    }
                    if($data['status'] && $uids) $attention->pushAttentionTips($uids, $data['member_id']);
                }
            }
            if(isset($at_members['member_ids']) && $at_members['member_ids']){
                $member_ids = array_values($at_members['member_ids']);
                $attention->addAttentionSortSet($member_ids, $data['member_id']);
            }

            if($method === 'edit'){
                $this->delete($id);
            }
            //用户post num 更新
            if($method != 'edit' && $data['category'] === 'posts'){
                Posts::updatePostNum($data['member_id']);
            }
        }catch (\Exception $e){
            echo $e->getMessage();
            return;
        }
        return $data;

    }



    //基于es的post list搜索条件
    public function postMapping($last_id, $page_size = 10, $following = [], $block =[], $top_id = null, $exclude_post_ids = [])
    {
        $params = [
            'index' => self::INDEX,
            'type'  => self::TYPE,
            'size' => $page_size,
            'body' => [
                'query' => [
                    'bool' => [
                        'filter' => [
                            [
                                'bool' => [
                                    'must' => [
                                        [
                                            'bool' => [
                                                'must_not' => [ 'terms' => ['category' => ['qa', 'hotnews'] ] ],
                                            ]
                                        ],
                                        [
                                            'bool' => [
                                                'must_not' => [ 'terms' => [ 'member_id' => $block ] ],
                                            ]
                                        ],
                                        [ 'match_phrase' => [ 'is_robot' => 0 ]],
                                        [ 'match_phrase' => [ 'status' => 1 ]],
                                        [ 'match_phrase' => [ 'is_whole' => 1 ]],
                                        [ 'match_phrase' => [ 'brand_topic_id' => 0 ]],
                                        [ 'match_phrase' => [ 'shop_score' => 0 ]],
                                        [
                                            'bool' => [
                                                'should' => [
                                                    [ 'match_phrase' => [ 'original' => 0 ]],
                                                    [ 'bool' => [
                                                        'must' => [
                                                            [ 'range' => [ 'original' => ['gt' => 0] ]],
                                                            [ 'terms' => [ 'member_id' => $following ] ],
                                                        ]
                                                    ]],
                                                ]
                                            ]
                                        ]
                                    ]
                                ]
                            ]
                        ]
                    ]
                ],
                'sort' => [
                    [ 'id' => [ 'order' => 'DESC'] ],
                ]
            ]
        ];
        if($top_id){
            $params['body']['query']['bool']['filter'][0]['bool']['must_not'][] =  [ 'match_phrase' => [ 'id' => $top_id ]];
        }

        //过滤ID
        if(!empty($exclude_post_ids))
        {
            $params['body']['query']['bool']['filter'][0]['bool']['must'][]  = [
                'bool' => [
                    'must_not' => [
                        'terms' => [ 'id' => $exclude_post_ids ]
                    ]
                ]
            ];
        }

        if($last_id) $params['body']['search_after'] = [$last_id];
        return $this->_search($params, $page_size);
    }


    private function _search($params, $page_size = 10)
    {
        $list = $this->search($params);
        return [
            'total' =>  $list['hits']['total'],
            'total_page' =>  ceil($list['hits']['total'] / $page_size),
            'list' => $list['hits']['total'] ? array_column($list['hits']['hits'], '_source') : []
        ];
    }

}